package cn.getech.data.metadata.service.impl;

import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.utils.PageUtils2;
import cn.getech.data.intelligence.common.utils.Query;
import cn.getech.data.metadata.api.gateway.model.dto.CollectionSetting;
import cn.getech.data.metadata.constant.YesOrNoEnum;
import cn.getech.data.metadata.entity.CollectionSystemModuleEntity;
import cn.getech.data.metadata.entity.meta.CollectionTableInfo;
import cn.getech.data.metadata.entity.meta.CollectionTask;
import cn.getech.data.metadata.mapper.CollectionSettingMapper;
import cn.getech.data.metadata.mapper.CollectionSystemModuleMapper;
import cn.getech.data.metadata.model.req.collectionsystemmodule.CollectionSystemModuleAddReq;
import cn.getech.data.metadata.model.req.collectionsystemmodule.CollectionSystemModuleDeleteReq;
import cn.getech.data.metadata.model.req.collectionsystemmodule.CollectionSystemModuleListModuleReq;
import cn.getech.data.metadata.model.req.collectionsystemmodule.CollectionSystemModuleUpdateReq;
import cn.getech.data.metadata.model.res.CollectionSystemModuleComboxRes;
import cn.getech.data.metadata.model.res.CollectionSystemModuleListRes;
import cn.getech.data.metadata.model.res.CollectionSystemModuleRes;
import cn.getech.data.metadata.model.res.owner.Owner;
import cn.getech.data.metadata.service.CollectionSystemModuleService;
import cn.getech.data.metadata.service.CollectionTableInfoService;
import cn.getech.data.metadata.service.CollectionTaskService;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service("collectionSystemModuleService")
public class CollectionSystemModuleServiceImpl extends ServiceImpl<CollectionSystemModuleMapper, CollectionSystemModuleEntity> implements CollectionSystemModuleService {
    @Autowired
    private CollectionTaskService collectionTaskService;
    @Autowired
    private CollectionTableInfoService collectionTableInfoService;
    @Autowired
    private CollectionSettingMapper collectionSettingMapper;

    @Override
    public List<CollectionSetting> selectConfigList(Integer tenantId) {
        return collectionSettingMapper.selectList(
                new QueryWrapper<CollectionSetting>()
                .eq(tenantId != null, "tenant_id", tenantId));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveOrUpdateModule(CollectionSystemModuleEntity entity) {
        CollectionSetting config = collectionSettingMapper.selectById(1);
        Integer tenantId = ShiroUtils.getTenantId();
        if (entity.getSmType() > config.getTreeLevelMax()) {
            throw new RRException(String.format("[%s]目录不能高于设置最大层级数%s",
                    entity.getSmName(), config.getTreeLevelMax()));
        }
        QueryWrapper<CollectionSystemModuleEntity> param = new QueryWrapper<CollectionSystemModuleEntity>()
                .eq("sm_name", entity.getSmName())
                .eq("parent_id", entity.getParentId())
                .eq(tenantId != null, "tenant_id", tenantId)
                .eq("sm_type", entity.getSmType());
        CollectionSystemModuleEntity temp = baseMapper.selectOne(param);
        if (temp != null) {
            baseMapper.update(entity, param);
            entity.setSmId(temp.getSmId());
        } else {
            baseMapper.insertModule(entity);
        }
        return 0;
    }


    @Override
    public PageUtils2<CollectionSystemModuleRes> queryPage(Map<String, Object> params) {
        IPage<CollectionSystemModuleRes> page = this.getBaseMapper().selectListPage((Page<CollectionSystemModuleRes>) new Query<CollectionSystemModuleRes>().getPage(params), params);
        //获取所有系统信息
        List<CollectionSystemModuleEntity> smTypes = this.getBaseMapper().selectList(new QueryWrapper<CollectionSystemModuleEntity>().eq("sm_type", 1));
        if(CollectionUtil.isNotEmpty(smTypes)){
            Map<Integer, String> collect = smTypes.stream().collect(Collectors.toMap(CollectionSystemModuleEntity::getSmId, CollectionSystemModuleEntity::getSmName));
            if(null != page){
                page.getRecords().forEach(collectionSystemModuleRes -> {
                    if(collectionSystemModuleRes.getSmType() == 2){
                        collectionSystemModuleRes.setSysName(collect.get(collectionSystemModuleRes.getParentId()));
                    }else if(collectionSystemModuleRes.getSmType() == 1){
                        collectionSystemModuleRes.setSysName(collectionSystemModuleRes.getSmName());
                    }
                });
            }
        }
        return new PageUtils2(page);
    }

    @Override
    public List<CollectionSystemModuleListRes> queryPage() {
        List<CollectionSystemModuleRes> list = baseMapper.listAll(new HashMap<>());
        return getSystemModule(list);
    }

    private List<CollectionSystemModuleListRes> getSystemModule(List<CollectionSystemModuleRes> list){
        if(list == null)
            return null;

        List<CollectionSystemModuleListRes> returnList  = new ArrayList<>();
        List<CollectionSystemModuleRes> systemList = list.stream().filter(sm -> sm.getSmType().intValue() == 1).collect(Collectors.toList());
        for(CollectionSystemModuleRes sm : systemList){
            CollectionSystemModuleListRes res = new CollectionSystemModuleListRes();
            res.setSmId(sm.getSmId());
            res.setSmType(sm.getSmType());
            res.setSmName(sm.getSmName());
            res.setIsDefalut(sm.getIsDefault() == null ? 0 : sm.getIsDefault());
            List<CollectionSystemModuleRes> moduleList = list.stream().filter(m -> m.getParentId().intValue() == sm.getSmId().intValue()).collect(Collectors.toList());
            res.setModules(moduleList);
            returnList.add(res);
        }

        return returnList;
    }

    @Override
    public List<Owner> listTree() {
        Integer tenantId = ShiroUtils.getTenantId();
        List<CollectionSystemModuleEntity> list = baseMapper.selectList(
                new QueryWrapper<CollectionSystemModuleEntity>()
                        .eq(tenantId != null, "tenant_id", tenantId)
                        .or()
                        .eq("sm_id",-1));
        List<Owner> listTrees = Lists.newArrayList();
        List<Owner> parentList=Lists.newArrayList();
        if (CollectionUtil.isNotEmpty(list)) {
            for (CollectionSystemModuleEntity moduleEntity : list) {
                Owner owner = new Owner(moduleEntity.getSmId(), moduleEntity.getSmName(), moduleEntity.getParentId());
                listTrees.add(owner);
                if (YesOrNoEnum.NO.getValue().equals(moduleEntity.getParentId())) {
                    parentList.add(owner);
                }
            }
            Map<Integer, List<Owner>> sysListMap = listTrees.stream().filter(s -> !YesOrNoEnum.NO.getValue().equals(s.getParentId()))
                    .collect(Collectors.groupingBy(Owner::getParentId));
            listTrees.forEach(s -> s.setChildren(sysListMap.get(s.getId())));
        }
        return parentList;
    }
    @Override
    public List<CollectionSystemModuleComboxRes> listSystem() {
        List<CollectionSystemModuleEntity> list = baseMapper.selectList(new QueryWrapper<CollectionSystemModuleEntity>().eq("sm_type", 1));//sm_type 1:是系统
        if(list == null)
            return null;

        List<CollectionSystemModuleComboxRes> returnList = new ArrayList<>();
        for(CollectionSystemModuleEntity entity : list){
            CollectionSystemModuleComboxRes res = new CollectionSystemModuleComboxRes();
            res.setSmId(entity.getSmId());
            res.setSmName(entity.getSmName());
            returnList.add(res);
        }
        return returnList;
    }

    @Override
    public List<CollectionSystemModuleComboxRes> listModule(CollectionSystemModuleListModuleReq req) {
        List<CollectionSystemModuleEntity> list = baseMapper.selectList(new QueryWrapper<CollectionSystemModuleEntity>().eq("sm_type", 2).eq("parent_id", req.getSystemId()));//sm_type 2:是模块
        if(list == null)
            return null;

        List<CollectionSystemModuleComboxRes> returnList = new ArrayList<>();
        for(CollectionSystemModuleEntity entity : list){
            CollectionSystemModuleComboxRes res = new CollectionSystemModuleComboxRes();
            res.setSmId(entity.getSmId());
            res.setSmName(entity.getSmName());
            returnList.add(res);
        }
        return returnList;
    }

    @Override
    public void save(CollectionSystemModuleAddReq req, Long userId) {
        if(req.getSmName().length() > 10)
            throw new RRException(req.getSmName()+"长度超过10个字");
        Integer tenantId = ShiroUtils.getTenantId();
        checkTreeMax(req.getSmType(), tenantId);
        QueryWrapper<CollectionSystemModuleEntity> queryWrapper = new QueryWrapper<CollectionSystemModuleEntity>()
                    .eq("sm_name", req.getSmName())
                    .eq("sm_type", req.getSmType())
                    .eq(tenantId != null, "tenant_id", tenantId)
                    .eq("parent_id", req.getParentId());
        Integer count = baseMapper.selectCount(queryWrapper);
        if(count > 0)
            throw new RRException("已经存在" + req.getSmName());
        CollectionSystemModuleEntity entity = new CollectionSystemModuleEntity();
        entity.setSmType(req.getSmType());
        entity.setSmName(req.getSmName());
        entity.setManager(req.getUserId());
        entity.setParentId(req.getParentId());
        entity.setCreatePer(userId);
        entity.setTenantId(tenantId);
        entity.setCreateTime(new Date());
        entity.setUpdatePer(userId);
        entity.setUpdateTime(entity.getCreateTime());
        baseMapper.insert(entity);
    }

    @Override
    public void update(CollectionSystemModuleUpdateReq req, Long userId) {
        if(req.getSmName().length() > 10)
            throw new RRException(req.getSmName()+"长度超过10个字");
        CollectionSystemModuleEntity old = baseMapper.selectById(req.getSmId());
        if(old == null)
            throw new RRException("没有该记录");
        Integer tenantId = ShiroUtils.getTenantId();
        checkTreeMax(req.getSmType(), tenantId);
        QueryWrapper<CollectionSystemModuleEntity> queryWrapper = null;
        {
            queryWrapper = new QueryWrapper<CollectionSystemModuleEntity>()
                    .eq("sm_name",req.getSmName())
                    .eq("sm_type", old.getSmType())
                    .eq("parent_id",req.getParentId())
                    .eq(tenantId != null, "tenant_id", tenantId)
                    .ne("sm_id", old.getSmId());
        }
        Integer count = baseMapper.selectCount(queryWrapper);
        if(count > 0)
            throw new RRException("已经存在" + req.getSmName());
        CollectionSystemModuleEntity entity = new CollectionSystemModuleEntity();
        entity.setSmId(req.getSmId());
        entity.setSmName(req.getSmName());
        entity.setManager(req.getUserId());
        entity.setSmType(req.getSmType());
        entity.setParentId(req.getParentId());
        entity.setUpdatePer(userId);
        entity.setUpdateTime(new Date());
        baseMapper.updateById(entity);
    }

    private void checkTreeMax(Integer smType, Integer tenantId) {
        List<CollectionSetting> configList = collectionSettingMapper.selectList(new QueryWrapper<CollectionSetting>()
                .eq(tenantId != null, "tenant_id", tenantId));
        if (CollectionUtil.isNotEmpty(configList)) {
            CollectionSetting config = configList.get(0);
            if (smType > config.getTreeLevelMax()) {
                throw new RRException("所属树目录层级超过设置数" + config.getTreeLevelMax());
            }
        } else{
            if (smType > 2) {
                throw new RRException("所属树目录层级超过设置数2");
            }
        }
    }

    @Override
    public void delete(CollectionSystemModuleDeleteReq req) {
        CollectionSystemModuleEntity old = baseMapper.selectById(req.getSmId());
        if (old == null)
            throw new RRException("没有该记录");
        if (req.getSmId() == -1) {
            throw new RRException("默认目录，不能删除");
        }
        Integer count = baseMapper.selectCount(new QueryWrapper<CollectionSystemModuleEntity>().eq("parent_id", req.getSmId()));
        if (count > 0)
            throw new RRException("该目录存在子目录，不能删除");

        //存在模块引用
        int moduleCount = collectionTaskService.count(new QueryWrapper<CollectionTask>().eq("own_module", req.getSmId()).eq("delete_flag", 0));
        if (moduleCount > 0)
            throw new RRException("该目录下存在采集任务，不能删除");

        moduleCount = collectionTableInfoService.count(new QueryWrapper<CollectionTableInfo>().eq("own_module", req.getSmId()).eq("delete_flag", 0));
        if (moduleCount > 0)
            throw new RRException("该目录下存在元数据，不能删除");
        baseMapper.deleteById(req.getSmId());
    }

    @Override
    public CollectionSystemModuleListRes getDefault() {
        Map<String,Object> params = new HashMap<>();
        params.put("isDefault", 1);
        List<CollectionSystemModuleRes> list = baseMapper.listAll(params);
        List<CollectionSystemModuleListRes> systemModule = getSystemModule(list);
        if(CollectionUtil.isEmpty(systemModule))
            return null;
        return systemModule.get(0);
    }
}
